package com.hoperun.checkcloth.net

import com.google.gson.Gson
import com.google.gson.JsonObject
import com.hoperun.checkcloth.entity.LeftOverBoltInfo
import com.hoperun.checkcloth.util.Logger
import com.hoperun.checkcloth.util.MD5Encrypt
import com.hoperun.checkcloth.util.fromJsonOrNull
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.toList
import java.lang.reflect.Type

class SoapApi(private val client: SoapClient = SoapClient()) {
    val logger = Logger.create("SoapApi")

    /***
     *  布头检验登录接口
     */
    suspend fun leftOverBoltLogin(account: String, password: String): Pair<String, JsonObject>? {
        val pwdMd5 = MD5Encrypt.MD5(password.trim())
        val request = LeftOverBoltLoginRequest(account, pwdMd5)
        val method = "login"

        val result = client.makeCall(method, Gson().toJson(request))
        val resp = parseResponse<LeftOverBoltLoginResponse>(result, LeftOverBoltLoginResponse::class.java)
        logger.d("Login Request request: $request, md5: ${Gson().toJson(request)}")
        logger.d("Login Request response: $resp")

        val userBean = resp.value?.userBean ?: return null
        return Pair(resp.value.name, userBean)
    }

    suspend fun leftOverBoltCommitFlawInfo(userBean: JsonObject, monadNo: String, flawList: List<ClothFlawInfo>): Boolean {
        val request = LeftOverBoltClothFlawInfoCommitRequest(userBean, monadNo, flawList)
        val method = "btClothQtyCheckDetailCommit"
        val result = client.makeCall(method, Gson().toJson(request))

        val resp = parseResponse<LeftOverBoltClothFlawInfoCommitResponse>(result, LeftOverBoltClothFlawInfoCommitResponse::class.java)
        logger.d("LeftOverBolt Commit Request $request")
        logger.d("LeftOverBolt Commit Response $resp")
        return "SUCCESS" == resp.value?.flag
    }

    /***
     * 布头检验系统，根据三联号获取相关信息接口
     */
    suspend fun leftOverBoltQueryByClothNo(monadNo: String): ApiResult<Triple<String, List<ClothFlawInfo>?, LeftOverBoltInfo?>?> {
        val request = LeftOverBoltClothNoQueryRequest(monadNo)
        val method = "btQueryByClothtktNo"

        val result = client.makeCall(method, Gson().toJson(request))
        val resp = parseResponse<LeftOverBoltInfoResponse>(result, LeftOverBoltInfoResponse::class.java)
        logger.d("LeftOverBolt Query request $request")
        logger.d("LeftOverBolt Query response $resp")


        resp.value?.let {
            return if (it.flag == "SUCCESS") {
                ApiResult(ApiOk, Triple(it.levelFlag ?: "", it.dataList, it.info))
            } else {
                ApiResult(ApiError(it.errMessage), null)
            }
        }

        return ApiResult(ApiError("数据解析异常"), null)
    }

    suspend fun grayClothLogin(account: String) {
        val request = GrayClothLoginRequest(account)
        val method = "zjPDALogin"

        client.makeCall(method, Gson().toJson(request))
    }

    suspend fun grayClothQueryByMonadNo(monadNo: String, account: String) {
        val request = GrayClothQueryRequest(monadNo, account)
        val method = "zjQueryByMonadNo"

        client.makeCall(method, Gson().toJson(request))
    }

    suspend fun grayClothCommitFlawInfo() {

    }

    suspend fun queryDataDict(id: String): Pair<List<DictItem>, List<DictItem>>? {
        val request = QueryDataDictRequest(id)
        val method = "querySJZDBySJZDID"

        val result = client.makeCall(method, Gson().toJson(request))
        val resp = parseResponse<QueryDataDictResponse>(result, QueryDataDictResponse::class.java)


        resp.value?.let {

            val flawList = flow {
                it.data1?.forEach { i -> emit(i) }
                it.data1?.size?.let {
                    repeat(16 - it) {
                        emit(DictItem())
                    }
                }
                it.data2?.forEach { i -> emit(i) }
                it.data3?.forEach { i -> emit(i) }
            }.toList()

            val remarks = flow { it.data4?.forEach { i -> emit(i) } }.toList()

            return flawList to remarks
        }

        return null

    }

    suspend fun queryNewVersion(): UpgradeInfo? {
        val request = GetNewVersionRequest()
        val method = "autoUpdate"

        val result = client.makeCall(method, Gson().toJson(request))
        val resp = parseResponse<GetNewVersionResponse>(result, GetNewVersionResponse::class.java)
        logger.d("queryNewVersion request $request")
        logger.d("queryNewVersion response $resp")
        return resp.value?.info
    }

    private fun <T> parseResponse(result: CallResult<String>, t: Type): CallResult<T?> {
        if (result.ok) {
            Gson().fromJsonOrNull<T>(result.value, t)?.let {
                return CallResult(true, it)
            }
        }
        return CallResult(false, null)
    }
}